package org.apache.poi.hwpf.converter;

import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.ListFormatOverride;
import org.apache.poi.hwpf.model.ListTables;
import org.apache.poi.hwpf.model.PicturesTable;
import org.apache.poi.hwpf.usermodel.*;
import org.apache.poi.util.POILogger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.awt.image.BufferedImage;
import java.io.*;

import static org.apache.poi.hwpf.converter.AbstractWordUtils.TWIPS_PER_INCH;

/**
 * User: zigang.wang
 * Date: 12-8-2
 * Time: 下午1:56
 */
public class DocToHtml extends WordToHtmlConverter {
    public DocToHtml(Document document) {
        super(document);
    }

    public DocToHtml(HtmlDocumentFacade htmlDocumentFacade) {
        super(htmlDocumentFacade);
    }

    static Element pageContainer;

     Document process(File docFile, HtmlDocumentFacade htmlDocumentFacade) throws Exception {
        final HWPFDocument wordDocument = new HWPFDocument(new FileInputStream(docFile));
        WordToHtmlConverter converter = new WordToHtmlConverter(htmlDocumentFacade);
        converter.processDocument(wordDocument);

       

        final SummaryInformation summaryInformation = wordDocument.getSummaryInformation();
        if(summaryInformation != null){
            if (WordToHtmlUtils.isNotEmpty(summaryInformation.getTitle()))
                htmlDocumentFacade.setTitle(summaryInformation.getTitle());

            if (WordToHtmlUtils.isNotEmpty(summaryInformation.getAuthor()))
                htmlDocumentFacade.addAuthor(summaryInformation.getAuthor());

            if (WordToHtmlUtils.isNotEmpty(summaryInformation.getKeywords()))
                htmlDocumentFacade.addKeywords(summaryInformation.getKeywords());

            if (WordToHtmlUtils.isNotEmpty(summaryInformation.getComments()))
                htmlDocumentFacade
                        .addDescription(summaryInformation.getComments());
        }
       
        final PicturesTable picstab = wordDocument.getPicturesTable() ;//可以保存的图片

       /* if (wordDocument.getPicturesTable().getAllPictures().size() > 0) {
            picstab = ;
        }*/

        final Range docRange = wordDocument.getRange();
        if ( docRange.numSections() == 1 ){
             htmlDocumentFacade.addStyleClass(htmlDocumentFacade.body, "b",
                     getSectionStyle(docRange.getSection(0)));
            htmlDocumentFacade.updateStylesheet();
        }else{
            for ( int s = 0; s < docRange.numSections(); s++ ){
//                processSection( wordDocument, docRange.getSection( s ), s );
                Section range = docRange.getSection(s);
                Element div = htmlDocumentFacade.createBlock();
                htmlDocumentFacade.addStyleClass(div, "d", getSectionStyle(range));
//      htmlDocumentFacade.body.appendChild( div );
                pageContainer.appendChild(div);

//                processParagraphes(wordDocument, div, section, Integer.MIN_VALUE);
                final ListTables listTables = wordDocument.getListTables();
                int currentListInfo = 0;

                    
                final int paragraphs = range.numParagraphs();
                for (int p = 0; p < paragraphs; p++) {
                    Paragraph paragraph = range.getParagraph(p);

//			加入图片
                    CharacterRun cr = paragraph.getCharacterRun(0);
//                    processImage(div, cr);
                    /**
                     * 加入图片
                     */
//                protected void processImage(Element parent, CharacterRun cr) {

                    OfficeDrawing officeDrawing = wordDocument.getOfficeDrawingsMain()
                            .getOfficeDrawingAt( cr.getStartOffset() );

                    byte[] pictureData = officeDrawing.getPictureData();
                    PictureType type = PictureType.findMatchingType( pictureData );
                    float width = ( officeDrawing.getRectangleRight() - officeDrawing
                            .getRectangleLeft() ) / AbstractWordUtils.TWIPS_PER_INCH;
                    float height = ( officeDrawing.getRectangleBottom() - officeDrawing
                            .getRectangleTop() ) / AbstractWordUtils.TWIPS_PER_INCH;
                    
                    String path = getPicturesManager()
                            .savePicture( pictureData, type,
                                    "s" + cr.getStartOffset() + "." + type,
                                    width, height );

                        if (picstab.hasPicture(cr)) {
                            Picture pic = picstab.extractPicture(cr, false);

                            String fileName = pic.suggestFullFileName();
                            OutputStream out = null;
                            try {

//					TWIPS_PER_INCH/
                               String output =  outputFile.substring(0, outputFile.lastIndexOf(".html")).concat(File.separator).concat("images").concat(File.separator);
                                out = new FileOutputStream(new File(output.concat(fileName)));
                                pic.writeImageContent(out);
                                Element img = htmlDocumentFacade.getDocument().createElement("img");
//                String uri = fileName.concat("image").concat(File.separator).concat(fileName);
                                String uri = output.concat(File.separator).concat(fileName);
                                img.setAttribute("src", uri);


                                ByteArrayInputStream is = new ByteArrayInputStream(pic.getRawContent());
                                BufferedImage image = ImageIO.read(is);
                                if (image.getWidth() > 600)
                                    img.setAttribute("style", "width: 600px;");
                                Element imgBlock = htmlDocumentFacade.createBlock();
                                htmlDocumentFacade.addStyleClass(imgBlock, "imgs", "text-align:center;");
                                imgBlock.appendChild(img);
                                div.appendChild(imgBlock);
                            } finally {
                                if (out != null)
                                        out.close();
                            }
                        }
                    //} 图片END
//          table
                    if (paragraph.isInTable()) {
                        Table table = range.getTable(paragraph);
//                        processTable(wordDocument, div, table);

                        /**
                         * 解析table
                         */
//                        protected void processTable(HWPFDocument hwpfDocument, Element flow, Table table) {
                            Element tableHeader = htmlDocumentFacade.createTableHeader();
                            Element tableBody = htmlDocumentFacade.createTableBody();

                            final int[] tableCellEdges = WordToHtmlUtils.buildTableCellEdgesArray(table);
                            final int tableRows = table.numRows();


                            int maxColumns = Integer.MIN_VALUE;
                            for (int r = 0; r < tableRows; r++) {
                                maxColumns = Math.max(maxColumns, table.getRow(r).numCells());
                            }

                            for (int r = 0; r < tableRows; r++) {
                                TableRow tableRow = table.getRow(r);

                                Element tableRowElement = htmlDocumentFacade.createTableRow();
                                StringBuilder tableRowStyle = new StringBuilder();


                                WordToHtmlUtils.addTableRowProperties(tableRow, tableRowStyle);

                                // index of current element in tableCellEdges[]
                                int currentEdgeIndex = 0;
                                final int rowCells = tableRow.numCells();
                                for (int c = 0; c < rowCells; c++) {
                                    TableCell tableCell = tableRow.getCell(c);

                                    if (tableCell.isVerticallyMerged() && !tableCell.isFirstVerticallyMerged()) {
                                        currentEdgeIndex += getNumberColumnsSpanned(tableCellEdges, currentEdgeIndex, tableCell);
                                        continue;
                                    }

                                    Element tableCellElement;
                                    if (tableRow.isTableHeader()) {
                                        tableCellElement = htmlDocumentFacade.createTableHeaderCell();
                                    } else {
                                        tableCellElement = htmlDocumentFacade.createTableCell();
                                    }
                                    StringBuilder tableCellStyle = new StringBuilder();
                                    WordToHtmlUtils.addTableCellProperties(tableRow, tableCell, r == 0, r == tableRows - 1, c == 0, c == rowCells - 1, tableCellStyle);

                                    int colSpan = getNumberColumnsSpanned(tableCellEdges,
                                            currentEdgeIndex, tableCell);
                                    currentEdgeIndex += colSpan;

                                    if (colSpan == 0)
                                        continue;

                                    if (colSpan != 1)
                                        tableCellElement.setAttribute("colspan",
                                                String.valueOf(colSpan));

                                    final int rowSpan = getNumberRowsSpanned(table,
                                            tableCellEdges, r, c, tableCell);
                                    if (rowSpan > 1)
                                        tableCellElement.setAttribute("rowspan",
                                                String.valueOf(rowSpan));

                                    processParagraphes(wordDocument, tableCellElement, tableCell,
                                            table.getTableLevel());

                                    if (!tableCellElement.hasChildNodes()) {
                                        tableCellElement.appendChild(htmlDocumentFacade
                                                .createParagraph());
                                    }
                                    if (tableCellStyle.length() > 0)
                                        htmlDocumentFacade.addStyleClass(tableCellElement,
                                                tableCellElement.getTagName(),
                                                tableCellStyle.toString());

                                    tableRowElement.appendChild(tableCellElement);
                                }

                                if (tableRowStyle.length() > 0)
                                    tableRowElement.setAttribute("class", htmlDocumentFacade
                                            .getOrCreateCssClass("r", tableRowStyle.toString()));

                                if (tableRow.isTableHeader()) {
                                    tableHeader.appendChild(tableRowElement);
                                } else {
                                    tableBody.appendChild(tableRowElement);
                                }
                            }

                            final Element tableElement = htmlDocumentFacade.createTable();
                            tableElement
                                    .setAttribute(
                                            "class",
                                            htmlDocumentFacade
                                                    .getOrCreateCssClass("t",
                                                            "table-layout:fixed;border-collapse:collapse;border-spacing:0;"));
                            if (tableHeader.hasChildNodes()) {
                                tableElement.appendChild(tableHeader);
                            }
                            if (tableBody.hasChildNodes()) {
                                tableElement.appendChild(tableBody);
                                div.appendChild(tableElement);
                            } else {
                               /* logger.log(POILogger.WARN, "Table without body starting at [",
                                        Integer.valueOf(table.getStartOffset()), "; ",
                                        Integer.valueOf(table.getEndOffset()), ")");*/
                            }
//                        }


                        p += table.numParagraphs();
                        p--;
                        continue;
                    }
//          换页
                    if (paragraph.text().equals("\u000c")) {
                        processPageBreak(wordDocument, div);
                    }
                    if (paragraph.getIlfo() != currentListInfo) {
                        currentListInfo = paragraph.getIlfo();
                    }
//          嵌套段落
                    if (currentListInfo != 0) {
                        /*if (listTables != null) {

                            final ListFormatOverride listFormatOverride = listTables.getOverride(paragraph.getIlfo());

                            String label = getBulletText(listTables, paragraph, listFormatOverride.getLsid());

                            if ("".equals(label)) {
                                itemSymbol = true;
                                *//*
                                Element span = htmlDocumentFacade.getDocument().createElement("span");
                                span.setAttribute("style", "font-size:12.0pt;line-height:150%;font-family:Wingdings;mso-ascii-font-family:Wingdings;mso-hide:none;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;font-weight:normal;mso-bidi-font-weight:normal;font-style:normal;mso-bidi-font-style:normal;text-underline:windowtext none;text-decoration:none;background:transparent");
                                span.setTextContent("Ø");
  
                                flow.appendChild(span);
                                *//*
                            }

                            processParagraph(wordDocument, flow, currentTableLevel, paragraph, label);
                        } else {
                          
                            processParagraph(wordDocument, flow, currentTableLevel,
                                    paragraph, AbstractWordUtils.EMPTY);
                        }*/
                    } else {
//                        processParagraph(wordDocument, flow, currentTableLevel, paragraph, AbstractWordUtils.EMPTY);
                    }
                }
            }
        }



        return converter.getDocument();
    }

    protected void processParagraphes(HWPFDocument wordDocument, Element flow, Range range, int currentTableLevel) {
        //TODO  mc process paragraphes

        final ListTables listTables = wordDocument.getListTables();
        int currentListInfo = 0;

//        final int paragraphs = range.numParagraphs();
        final int paragraphs = range.numParagraphs();
        for (int p = 0; p < paragraphs; p++) {
            Paragraph paragraph = range.getParagraph(p);

//			加入图片
            CharacterRun cr = paragraph.getCharacterRun(0);
//            processImage(flow, cr);
//          table
            if (paragraph.isInTable() && paragraph.getTableLevel() != currentTableLevel) {
                if (paragraph.getTableLevel() < currentTableLevel)
                    throw new IllegalStateException("Trying to process table cell with higher level (" + paragraph.getTableLevel() + ") than current table level (" + currentTableLevel + ") as inner table part");

                Table table = range.getTable(paragraph);
                processTable(wordDocument, flow, table);

                p += table.numParagraphs();
                p--;
                continue;
            }
//          换页
            if (paragraph.text().equals("\u000c")) {
                processPageBreak(wordDocument, flow);
            }
            if (paragraph.getIlfo() != currentListInfo) {
                currentListInfo = paragraph.getIlfo();
            }
//          嵌套段落
            if (currentListInfo != 0) {
                if (listTables != null) {

                    final ListFormatOverride listFormatOverride = listTables.getOverride(paragraph.getIlfo());

               /*     String label = getBulletText(listTables, paragraph, listFormatOverride.getLsid());

                    if ("".equals(label)) {
                        itemSymbol = true;
                        *//*
                              Element span = htmlDocumentFacade.getDocument().createElement("span");
                              span.setAttribute("style", "font-size:12.0pt;line-height:150%;font-family:Wingdings;mso-ascii-font-family:Wingdings;mso-hide:none;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;font-weight:normal;mso-bidi-font-weight:normal;font-style:normal;mso-bidi-font-style:normal;text-underline:windowtext none;text-decoration:none;background:transparent");
                              span.setTextContent("Ø");

                              flow.appendChild(span);
                              *//*
                    }*/

//                    processParagraph(wordDocument, flow, currentTableLevel, paragraph, label);
                } else {

                }
            } else {
                processParagraph(wordDocument, flow, currentTableLevel, paragraph, AbstractWordUtils.EMPTY);
            }
        }

    }


    private static String getSectionStyle(Section section) {
        float leftMargin = section.getMarginLeft() / TWIPS_PER_INCH;
        float rightMargin = section.getMarginRight() / TWIPS_PER_INCH;
        float topMargin = section.getMarginTop() / TWIPS_PER_INCH;
        float bottomMargin = section.getMarginBottom() / TWIPS_PER_INCH;

        String style = "margin: " + topMargin + "in " + rightMargin + "in " + bottomMargin + "in " + leftMargin + "in;";

        if (section.getNumColumns() > 1) {
            style += "column-count: " + (section.getNumColumns()) + ";";
            if (section.isColumnsEvenlySpaced()) {
                float distance = section.getDistanceBetweenColumns() / TWIPS_PER_INCH;
                style += "column-gap: " + distance + "in;";
            } else {
                style += "column-gap: 0.25in;";
            }
        }
        return style;
    }

   static String outputFile = "D:\\testjod\\doc\\test2.html";
    public static void main(String[] args) {
        try {
            String inputFile = "D:\\testjod\\test.doc";
            
           
            HtmlDocumentFacade facade =
                    new HtmlDocumentFacade(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());

            String s1 = "background-color:gray";
            facade.addStyleClass(facade.body, "body", s1);
            Document document = facade.getDocument();
            Element window = document.createElement("div");
            Element center = document.createElement("center");
            center.appendChild(window);
            facade.addStyleClass(window, "window", "border:2px solid green;width:800px!important; margin:0 auto; background-color:#fff; text-align:left;");
            facade.body.appendChild(center);

            pageContainer = window;


       /*     String outputImgDir = outputFile.substring(0, outputFile.lastIndexOf(".html")).concat(File.separator).concat("images").concat(File.separator);
            // get fileName
            new File(outputImgDir).mkdirs();
            */
            



//            Document doc = DocToHtml.process(new File(inputFile), facade);
            Document doc = DocToHtml.process(new File(inputFile));

            FileWriter out = new FileWriter(outputFile);
            DOMSource domSource = new DOMSource(doc);
            StreamResult streamResult = new StreamResult(out);

            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer serializer = tf.newTransformer();
            // TODO set encoding from a command argument
            serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
            serializer.setOutputProperty(OutputKeys.METHOD, "html");
            serializer.transform(domSource, streamResult);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }
}
